<?php

class Rapide_Router implements Rapide_Router_Interface
{
	private
		$_oConfig,
		$_iUrlLevel = 0;

	public function __construct()
	{
		$this->_oConfig = new Rapide_Config;

		$this->_oConfig->load('Router.php');
		$this->_oConfig->load('Controller.php');
	}

	/**
	 * Run router and get token of the request
	 *
	 * @return Rapide_Dispatcher_Token token
	 */
	public function execute()
	{
		$sControllerAccessor = $this->_oConfig->get('Router', 'accessor', 'controller');
		$sActionAccessor = $this->_oConfig->get('Router', 'accessor', 'action');

		$sDefaultController	= $this->_oConfig->get('Controller', 'default', 'controller');
		$sDefaultAction = $this->_oConfig->get('Controller', 'default', 'action');

		if(isset($_GET[$sControllerAccessor]))
			$sController = $_GET[$sControllerAccessor];
		else
			$sController = $sDefaultController;

		if(isset($_GET[$sActionAccessor]))
			$sAction = $_GET[$sActionAccessor];
		else
			$sAction = $sDefaultAction;

		/**
		 * TODO: ucfirst - is that router's task or token's?
		 */
		$oToken = new Rapide_Dispatcher_Token(ucfirst($sController), ucfirst($sAction), $_GET);

		return $oToken;
	}

	/**
	 * Get valid URL
	 *
	 * @param string $sController
	 * @param string $sAction
	 * @param array $aParameters for controller
	 * @param bool $bSSL
	 * @return string URL
	 */
	public function url($sController = null, $sAction = null, array $aParameters = array(), $bSSL = null)
	{
		$sControllerAccessor = $this->_oConfig->get('Router', 'accessor', 'controller');
		$sActionAccessor = $this->_oConfig->get('Router', 'accessor', 'action');

		$bSSL = isset($bSSL) ? (bool)$bSSL : $this->_oConfig->get('Router', 'ssl');

		$sURL = ($bSSL ? 'https' : 'http') . '://' . $this->_getUrl() . '/';

		if(isset($sController))
		{
			$sURL .= '?' . $sControllerAccessor . '=' . $sController;

			if(isset($sAction))
			{
				$sURL .= '&' . $sActionAccessor . '=' . $sAction;

				if(count($aParameters))
				{
					foreach($aParameters as $sParameter => $mValue)
						$sURL .= '&' . $sParameter . '=' . $mValue;
				}
			}
		}

		return $sURL;
	}
	
	/**
	 * Cut url of $this->_iUrlLevel levels.
	 * default: 0 - not cut.
	 */
	private function _getUrl() {

		$sUrl = $this->_oConfig->get('Router', 'url');

		if($this->_iUrlLevel) {
			$iUrlLevel = 0;
			for($i = strlen($sUrl) - 1; $i > 0; $i--) {
				if($sUrl{$i} == '/') $iUrlLevel++;
				
				if($this->_iUrlLevel == $iUrlLevel) {
					$sUrl = substr($sUrl, 0, $i);
					break;
				}
			}
		}

		return $sUrl;
	}

	/**
	 * Set level for generating URL
	 * 
	 * <p>Useful for generating URLs in backend for frontend.</p>
	 * <p>For example: if backend's directory is example.com/admin,
	 * user setUrlLevel(1) to generate valid url for example.com.</p>
	 * <p>Note, that backend's router MUST BE the same as frontend's.</p>
	 *
	 * @param int $iUrlLevel
	 */
	public function setUrlLevel($iUrlLevel = 0) {
		$this->_iUrlLevel = (int)$iUrlLevel;
	}
}

?>